package com.Listeners;

import com.SelfHome.Main;
import com.SelfHome.Variable;
import com.Util.Home;
import com.Util.HomeAPI;
import com.Util.MySQL;
import com.Util.Util;
import net.md_5.bungee.api.chat.BaseComponent;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;

import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;





public class BlockPlaceListener
  implements Listener
{
	
    public static HashMap<String,Integer> border_redis = new HashMap<String,Integer>();
	
	
  @EventHandler(priority = EventPriority.HIGHEST)
  public void BlockCanBuildEvent(BlockPlaceEvent event) {

    if (event.getPlayer().getName().toUpperCase().contains("AS-FAKEPLAYER") || 
      event.getPlayer().getName().toUpperCase().contains("[MINECRAFT]") || 
      event.getPlayer().getName().toUpperCase().contains("[MEKANISM]") || 
      event.getPlayer().getName().toUpperCase().contains("[IF]")
      ||
      event.getPlayer().getName().toUpperCase().contains("[depolyer]".toUpperCase())
      ||
      event.getPlayer().getName().toUpperCase().contains("[XU2FakePlayer]".toUpperCase())
      ||
      event.getPlayer().getName().toUpperCase().contains("[Modular Routers]".toUpperCase())
      
    		) {
      return;
    }
    
    Player p = event.getPlayer();
    
    if (event.getBlock() == null) {
      return;
    }
    
    if (Variable.Debug.contains(p.getName())) {
      p.sendMessage("§e§l§m--------------§7[§eDeBug§7]§e§l§m--------------");
      TextComponent Send_Block_Message = new TextComponent(
          "§eGet-Returned:§d" + Util.getNBTString(event.getBlock().getState()) + " §b>> §dCopy");
      Send_Block_Message.setClickEvent(
          new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, Util.getNBTString(event.getBlock().getState())));
      p.spigot().sendMessage((BaseComponent)Send_Block_Message);
      p.sendMessage("§e§l§m--------------§7[§eDeBug§7]§e§l§m--------------");
    } 
    
    if (!Util.CheckIsHome(event.getPlayer().getWorld().getName().replace(Variable.world_prefix, ""))) {
      return;
    }
    
//    if (event.getPlayer().getWorld().getWorldBorder().getCenter().getChunk() == event.getBlock().getChunk()) {
//        for (int c = 0; c < Main.JavaPlugin.getConfig().getStringList("ProhibitPlaceInCenter").size(); c++) {
//          String temp = Main.JavaPlugin.getConfig().getStringList("ProhibitPlaceInCenter").get(c);
//          if (Util.getNBTString(event.getBlock().getState()).toUpperCase().contains(temp.toUpperCase())) {
//            event.setCancelled(true);
//            event.getPlayer().sendMessage("§c§l区块保护 §f§l>>> §f请勿在世界中心区块放置此物品");
//            if(event.getPlayer().getItemInHand().getType().toString().toUpperCase().contains("CABLE")) {
//            	ItemStack i = event.getPlayer().getItemInHand();
//            	if(i.getAmount()==1) {
//            		event.getPlayer().setItemInHand(null);
//            	}else {
//            		i.setAmount(i.getAmount()-1);
//            		event.getPlayer().setItemInHand(i);
//            	}
//            }
//          } 
//        }
//    }
    
    
    
    if (Main.JavaPlugin.getConfig().getBoolean("CustomTileMax")) {
      
        Block block = event.getBlock();
        String nbt = Util.getNBTString(block.getState());
        boolean check_contain = false;
        String contain_nbt = "";
        int MaxThisTile = 0;
        for (int d = 0; d < Main.JavaPlugin.getConfig().getStringList("TileList").size(); d++) {
          String[] temp = ((String)Main.JavaPlugin.getConfig().getStringList("TileList").get(d)).split("\\|");
          if (temp[0].equalsIgnoreCase("chunk"))
          {
            
            if (nbt.toUpperCase().contains(temp[1].toUpperCase())) {
              check_contain = true;
              contain_nbt = temp[1];
              MaxThisTile = Integer.valueOf(temp[2]).intValue();
              break;
            }  } 
        } 
        if (check_contain) {
        	int NowAmount = 0;

            
            boolean extra_perm = false;
            int extra_amount = MaxThisTile;
            for (int i = 100; i > 0; i--) {
              if (p.hasPermission("SelfHome.ChunkPlace." + contain_nbt + "." + i)) {
                extra_perm = true;
                if (extra_amount < i) {
                  extra_amount = i;
                  break;
                } 
              } 
            }
            
            
            Home home = HomeAPI.getHome(event.getBlock().getWorld().getName().replace(Variable.world_prefix, ""));
            for(String str:home.getLimitBlock()) {
            	String[] args = str.split("\\|");
            	
            	int start_amount = 0;
            	for(int e=0;e<Main.JavaPlugin.getConfig().getStringList("TileList").size();e++) {
            		String[] temp = Main.JavaPlugin.getConfig().getStringList("TileList").get(e).split("\\|");
            		if(temp[0].equalsIgnoreCase("chunk") && nbt.toUpperCase().contains(temp[1].toUpperCase())) {
            			start_amount = Integer.valueOf(args[2]);
            			break;
            		}
            	}
            	
            	
            	if(args[0].equalsIgnoreCase("chunk") && nbt.toUpperCase().contains(args[1].toUpperCase())) {
            		int amount = Integer.valueOf(args[2]) + start_amount;
            		if(extra_amount < amount) {
            			extra_perm = true;
            			extra_amount = amount;
            		}
            	}
            }
            
            
            
            

            for (BlockState state:event.getBlock().getChunk().getTileEntities()) {
              if (Util.getNBTString(state).toUpperCase().contains(contain_nbt.toUpperCase())) {
                NowAmount++;
                
                if (Main.JavaPlugin.getConfig().getBoolean("EnableClearExtraBlocks") && 
                  NowAmount > MaxThisTile) {
                  event.setCancelled(true);
                  state.getBlock().getLocation().getWorld().getBlockAt(state.getBlock().getLocation()).setType(Material.AIR);
                  p.sendMessage(Variable.Lang_YML.getString("ClearExtraBlocks"));
                } 
              } 
              
              }
            
            NowAmount--;

            
            if (extra_perm) {
              MaxThisTile = extra_amount;
            }
            
            if (NowAmount + 1 <= MaxThisTile) {
              String temp = Variable.Lang_YML.getString("PlaceMaxTile");
              if (temp.contains("<Now>")) {
                temp = temp.replace("<Now>", String.valueOf(NowAmount + 1));
              }
              if (temp.contains("<Max>")) {
                temp = temp.replace("<Max>", String.valueOf(MaxThisTile));
              }
              if (temp.contains("<NBT>")) {
                temp = temp.replace("<NBT>", String.valueOf(contain_nbt));
              }
              p.sendMessage(temp);
            } else {
              String temp = Variable.Lang_YML.getString("PlaceReachMaxTile");
              if (temp.contains("<Now>")) {
                temp = temp.replace("<Now>", String.valueOf(NowAmount));
              }
              if (temp.contains("<Max>")) {
                temp = temp.replace("<Max>", String.valueOf(MaxThisTile));
              }
              if (temp.contains("<NBT>")) {
                temp = temp.replace("<NBT>", String.valueOf(contain_nbt));
              }
              event.setCancelled(true);
              p.sendMessage(temp);
            }
        }
        
    	
    }

    
    
	Home home = HomeAPI.getHome(p.getWorld().getName());
	   int vip_add = 0;
 	  ArrayList<String> players = new ArrayList<String>();
 	  players.add(home.getName());
 	  for(String op:home.getOPs()) {
 		  if(Bukkit.getPlayer(op) != null) {
 			  players.add(op);
 		  }
 	  }
       for(String s:Main.JavaPlugin.getConfig().getStringList("VIPAdd")) {
     	  String[] ss = s.split(",");
     	  for(String p_name : players) {
     		  Player pe = Bukkit.getPlayer(p_name);
     		  if(pe==null) {
     			  continue;
     		  }
     		  if(pe.hasPermission(ss[0])) {
     			  int add = Integer.valueOf(ss[1]);
     			  if(add > vip_add) {
     				  vip_add = add;
     			  }
     		  }
     		  
     	  }
       }
       
       
       
       if(border_redis.containsKey(home.getName())) {
           if(vip_add < border_redis.get(home.getName())) {
               vip_add = border_redis.get(home.getName());
           }else {
     		  border_redis.put(home.getName(), vip_add);
     	  }
       }else {
           border_redis.put(home.getName(), vip_add);
       }
       
	
    
    

    double set_x = 0.0D;
    double min_x = 0.0D;
    double set_z = 0.0D;
    double min_z = 0.0D;
    
    
    int level = home.getLevel();
    		set_x = p.getWorld().getSpawnLocation().getX() + vip_add + Main.JavaPlugin.getConfig().getInt("WorldBoard") / 2 + (
	        Main.JavaPlugin.getConfig().getInt("UpdateRadius") / 2 * (level-1) ); ;
	        min_x = p.getWorld().getSpawnLocation().getX() - vip_add - Main.JavaPlugin.getConfig().getInt("WorldBoard") / 2 - (
    Main.JavaPlugin.getConfig().getInt("UpdateRadius") / 2 * (level-1) );
	        set_z = p.getWorld().getSpawnLocation().getZ() + vip_add +  + Main.JavaPlugin.getConfig().getInt("WorldBoard") / 2 + (
    Main.JavaPlugin.getConfig().getInt("UpdateRadius") / 2 * (level-1));
	        min_z = p.getWorld().getSpawnLocation().getZ() - vip_add - Main.JavaPlugin.getConfig().getInt("WorldBoard") / 2  - (
    Main.JavaPlugin.getConfig().getInt("UpdateRadius") / 2 * (level-1));

    
    if (set_x < min_x) {
      double temp = set_x;
      set_x = min_x;
      min_x = temp;
    } 
    
    if (set_z < min_z) {
      double temp = set_z;
      set_z = min_z;
      min_z = temp;
    } 
    
    if (event.getBlock().getLocation().getX() <= min_x || event.getBlock().getLocation().getX()>= set_x || 
    		event.getBlock().getLocation().getZ()<= min_z || event.getBlock().getLocation().getZ()>= set_z) {
    	event.setCancelled(true);
    }
    
    
    
    
  }
}


